package eu.goldenak.ircbot;

import java.util.Timer;
import java.util.Vector;

/**
 * The TimerManager will provide the bot with timer functionality, surprisingly.
 * It uses the Timer and TimerTask classes from the Java API to keep things 
 * simple and straightforward. The TimerTask class has been extended with custom
 * constructors for easy creation and registration of BotTimers.
 */
public class TimerManager {
	
	/**
	 * The one and only instance to this class.
	 */
	private static final TimerManager s_pInstance = new TimerManager ();
	
	/**
	 * This Vector will hold the pointers to all registered BotTimers, for
	 * retrieval purposes and unregistering.
	 */
	private Vector <BotTimer> m_vTimers;
	
	/**
	 * The daemon thread where all BotTimers will be run in.
	 */
	private Timer m_pTimerThread;
	
	/**
	 * The constructor sets up the Vector where all the pointers to the
	 * BotTimers will be stored in. Also the Timer thread is setup.
	 */
	private TimerManager () {
		m_vTimers = new Vector <BotTimer> ();
		m_pTimerThread = new Timer (true);
	}
	
	/**
	 * To ensure we don't get multiple TimerManagers floating around in our bot,
	 * we are using the Singleton pattern once again.
	 */
	public static TimerManager getInstance () {
		return s_pInstance;
	}
	
	/**
	 * This method will give one the functionality of adding a BotTimer to the
	 * TimerManager, after which it eventually execute, if all is setup
	 * correctly by the programmer who created the BotTimer of course.
	 */
	public int register (BotTimer pTimer) {
		System.out.println ("Adding timer.");
		
		m_vTimers.add (pTimer);
		
		if (pTimer.isRepeating ()) {
			m_pTimerThread.schedule (pTimer, pTimer.getInterval (), pTimer.getInterval ());
		} else {
			m_pTimerThread.schedule (pTimer, pTimer.getInterval ());
		}
		
		return m_vTimers.indexOf (pTimer);
	}
	
	/**
	 * Unregisters a BotTimer using a pointer.
	 */
	public boolean unregister (BotTimer pTimer) {
		pTimer.cancel ();
		m_vTimers.remove (pTimer.getTimerId ());
		
		return true;
	}
	
	/**
	 * Unregisters a BotTimer by its ID. Returns true if the BotTimer was 
	 * successfully unregistered.
	 */
	public boolean unregister (int nTimerId) {
		try {
			BotTimer pTimer = m_vTimers.get (nTimerId);
			return unregister (pTimer);
		} catch (ArrayIndexOutOfBoundsException pException) {
			return false;
		}
	}
	
	/**
	 * Returns a pointer to the specified BotTimer ID.
	 */
	public BotTimer getBotTimer (int nTimerId) {
		try {
			return m_vTimers.get (nTimerId);
		} catch (ArrayIndexOutOfBoundsException pException) {
			return null;
		}
	}
}